package com.sxhuayuan.parking.plugin.parking.lifang;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.sxhuayuan.parking.compenent.Message;
import com.sxhuayuan.parking.compenent.web.RespMessage;
import com.sxhuayuan.parking.config.Platform;
import com.sxhuayuan.parking.dto.CreateMcardChargeOrderDTO;
import com.sxhuayuan.parking.dto.ParkFeeCacheBean;
import com.sxhuayuan.parking.entity.Member;
import com.sxhuayuan.parking.entity.MemberCarPlate;
import com.sxhuayuan.parking.entity.Order;
import com.sxhuayuan.parking.entity.ParkingIn;
import com.sxhuayuan.parking.entity.ParkingLot;
import com.sxhuayuan.parking.exception.MyException;
import com.sxhuayuan.parking.plugin.parking.ParkingPlugin;
import com.sxhuayuan.parking.plugin.parking.lifang.request.AddChargeinfoRequest;
import com.sxhuayuan.parking.plugin.parking.lifang.request.ChargeSourceEnum;
import com.sxhuayuan.parking.plugin.parking.lifang.request.GetCarInfoRequest;
import com.sxhuayuan.parking.plugin.parking.lifang.result.GetCarInfoResult;
import com.sxhuayuan.parking.plugin.parking.lifang.result.LifangAESUtils;
import com.sxhuayuan.parking.plugin.parking.result.McardCancelResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardChargeOrderCreateResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardQueryChargeOptionsResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardQueryResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.ParkingLotInfoQueryResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.QueryParkingFeeResultWrap;
import com.sxhuayuan.parking.queue.msg.NotifyParkingLotMsg;
import com.sxhuayuan.parking.service.OrderService;
import com.sxhuayuan.parking.service.ParkingInOutService;
import com.sxhuayuan.parking.service.ParkingInService;
import com.sxhuayuan.parking.service.ParkingLotService;
import com.sxhuayuan.parking.utils.DateUtils;

/**
 * 立方停车
 *
 * @author gy
 */
@Component(LifangParkingPlugin.ID)
public class LifangParkingPlugin extends ParkingPlugin {

	public static final String ID = "lifangParkingPlugin";

	Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private ParkingLotService lotService;
	@Autowired
	private OrderService orderService;
	@Autowired
	private ParkingInService inService;
	@Autowired
	private ParkingInOutService inOutService;

	@Override
	public String getId() {
		return ID;
	}

	@Override
	public String getName() {
		return "立方停车";
	}

	@Override
	public boolean isSupportOrderNotify() {
		return true;
	}

	@Override
	public boolean isSupportEventPush() {
		return true;
	}

	@Override
	public boolean isOpenNotifyWhileDebug() {
		return true;
	}

	@Override
	public ParkFeeCacheBean saveParkInRecord(String lotSn, String carPlate, String resp) {
		GetCarInfoResult gr = JSONObject.parseObject(resp, GetCarInfoResult.class);
		ParkFeeCacheBean bean = new ParkFeeCacheBean();
		bean.setParkPluginId(ID);
		bean.setCarPlate(carPlate);
		bean.setEndTime(DateUtils.parse(gr.getPayTime()));
		bean.setTotalFee(gr.getChargeMoney() / 100f);
		bean.setDiscountFee(gr.getJMMoney() / 100f);
		ParkingLot lot = lotService.findBySn(lotSn);
		ParkingIn in = inService.findByCarPlate(lot.getId(), carPlate);
		if (in == null) {
			log.info("未找到入场记录，创建入场记录");
			in = inService.enter(lot, carPlate, DateUtils.parse(gr.getInTime()), null, lot.getFreeMinutes(), null);
		}
		bean.setUniqueId(in.getUniqueId());
		log.debug("saveParkInRecord is = {}", JSONObject.toJSONString(bean));
		return bean;
	}

	// 请求算费
	@Override
	public QueryParkingFeeResultWrap queryParkingFee(ParkingLot lot, String carPlate) {
		log.debug("调用接口查询停车费: lotSn={}, carPlate={}", lot, carPlate);
		GetCarInfoRequest request = new GetCarInfoRequest();
		request.setCarCode(carPlate);
		String rJson = JSONObject.toJSONString(request);
		QueryParkingFeeResultWrap qr = new QueryParkingFeeResultWrap();
		qr.setIsSuccess(false);
		try {
			String res = httpPost(lot, "/GetCarInfo", rJson);
			if (StringUtils.isEmpty(res)) {
				qr.setMsg("查询失败");
				return qr;
			}
			GetCarInfoResult gr = JSONObject.parseObject(res, GetCarInfoResult.class);
			if (gr.getResCode() != 0) {
				qr.setMsg("未找到车辆");
				return qr;
			}
			String inTime = gr.getInTime();
			Integer paidMoney = gr.getPaidMoney();
			// 如果算费实付为0 则不入入场记录
			if (paidMoney != null && paidMoney != 0) {
				inService.enter(lot, carPlate, DateUtils.parse(inTime), null, lot.getFreeMinutes(), null);
			}
			qr.setCarPlate(carPlate);
			qr.setEntertime(inTime);
			qr.setCalcStartTime(inTime);
			qr.setCalcEndTime(gr.getPayTime());
			String parkingSeconds = gr.getParkingSeconds();
			int parkTime = 0;
			if (StringUtils.isEmpty(parkingSeconds))
				parkTime = (int) ((DateUtils.parse(gr.getPayTime()).getTime() - DateUtils.parse(gr.getInTime()).getTime()) / (60 * 1000));
			else
				parkTime = (int) Math.ceil(Long.valueOf(parkingSeconds) / 60f);
			qr.setParktimeMinute(parkTime);
			qr.setCalcFee(gr.getChargeMoney() / 100f);
			Float fee = gr.getPaidMoney() / 100f;
			qr.setFee(fee);
			Long uniqueId = submitUpdateOriginalInfoTask(lot.getSn(), carPlate, fee, res);
			qr.setUniqueId(uniqueId != null ? String.valueOf(uniqueId) : "");
			qr.setIsSuccess(true);
		} catch (MyException e) {
			log.warn(e.getMessage());
			qr.setIsSuccess(false);
			qr.setMsg(e.getMessage());
		} catch (Exception e) {
			log.error("", e);
			qr.setIsSuccess(false);
			qr.setMsg(e.getMessage());
		}
		return qr;
	}

	/**
	 * 6秒超时
	 *
	 * @param lot
	 * @param uri
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String httpPost(ParkingLot lot, String uri, String data) {
		// String encrypt = LifangAESUtils.encrypt(lot.getApiKey(), data);
		// log.debug("jiali is = {}", encrypt);
		Map<String, String> headers = new HashMap<>();
		headers.put("Content-Type", "application/json;charset=utf-8");
		headers.put("Accept", "application/json;charset=utf-8");
		String resp = postJson(lot.getSn(), lot.getApiUrl() + uri, data, headers, lot.getIsTcp());
		// String result = LifangAESUtils.decode(lot.getApiKey(), resp);
		// log.debug("jiemi is = {}", resp);
		return resp;
	}

	@Override
	public QueryParkingFeeResultWrap queryLeavingCarParkingLotOrder(ParkingLot lot, String exitSn, Member member) {
		// TODO Auto-generated method stub
		return null;
	}

	// 支付结果下发
	@Override
	public boolean notifyParkingFeeOrderSuccess(NotifyParkingLotMsg notify) {
		log.debug("支付下发 notify = {}", JSONObject.toJSONString(notify));
		String orderSn = notify.getLocalOrderSn();
		String lotSn = notify.getLocalLotSn();
		String carPlate = notify.getCarPlate();
		Order order = orderService.findBySn(orderSn);
		log.debug("order = {} ::: {}", order.getMoney(), order.getSn());
		ParkingLot lot = lotService.findBySn(lotSn);
		AddChargeinfoRequest ar = new AddChargeinfoRequest();
		ar.setCarCode(carPlate);
		int paidMoney = (int) (order.getMoney().floatValue() * 100);
		int JMMoney = (int) (order.getTotalDiscount().floatValue() * 100);
		ar.setChargeMoney(paidMoney + JMMoney);
		ar.setPaidMoney(paidMoney);
		ar.setJMMoney(JMMoney);
		ar.setPayTime(DateUtils.format(order.getEndtime()));
		ar.setChargeType(11);
		// 判定是微信支付还是支付宝 微信3 支付宝2
		// ar.setChargeSource(ChargeSourceEnum.getByName(order.getPlatform().name()).getCode());
		Platform form = order.getPlatform();
		ar.setChargeSource(form.equals(Platform.alipay) ? "2" : (form.equals(Platform.weixin) ? "3" : "0"));
		String res = httpPost(lot, "/AddChargeInfo", JSONObject.toJSONString(ar));
		if (res == null) {
			throw new MyException(RespMessage.Status.ERROR, Message.COMMON_SERVER_CONNECTION_FAILURE);
		}
		log.debug("支付结果下发  返回数据 == {}", res);
		JSONObject result = JSONObject.parseObject(res);
		int code = result.getInteger("resCode");
		if (code == 0)
			return true;
		return false;
	}

	@Override
	public boolean notifyMonthCardChargeOrderSuccess(String order, String lotSn, String carPlate) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public McardQueryResultWrap monthCardQuery(String lotSn, MemberCarPlate carPlate) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public McardQueryResultWrap monthCardChargePreview(String lotSn, String carPlate, Integer month) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ParkingLotInfoQueryResultWrap parkingLotInfoQuery(String lotSn) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public McardQueryChargeOptionsResultWrap monthCardQueryChargeOptions(String lotSn) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public McardChargeOrderCreateResultWrap monthCardCreateOrder(MemberCarPlate memberCarPlate, CreateMcardChargeOrderDTO dto, Platform platform) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public McardCancelResultWrap monthCardCancel(String lotSn, String carPlate) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String execute(String api, String lotSn, Map map) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void afterInNoticeHanler(HttpServletRequest request, HttpServletResponse response, ParkingLot parkingLot) {
		// TODO Auto-generated method stub

	}

	@Override
	public void afterOutNoticeHanler(HttpServletRequest request, HttpServletResponse response, ParkingLot parkingLot) {
		// TODO Auto-generated method stub

	}
	
	@Override
	public void beforeOutNoticeHandler(HttpServletRequest request, HttpServletResponse response, ParkingLot parkingLot) {
		// TODO Auto-generated method stub
		
	}

	public static void main(String[] args) throws Exception {
		byte[] ke = LifangAESUtils.initSecretKey();
		String key = Base64.encodeBase64String(ke);
		System.out.println("key = " + key);
		String str = "{\"a\":\"a\",\"b\":\"b\"}";
		String kjiami = LifangAESUtils.encrypt(key, str);
		System.out.println("kjiami = " + kjiami);
		String kjiemi = LifangAESUtils.decode(key, kjiami);
		System.out.println("kjiemi = " + kjiemi);

		ChargeSourceEnum a = ChargeSourceEnum.getByName("alipay");
		long l = (long) Math.ceil(8865 / 60f);
		double d = 8865 / 60f;
		System.out.println(l + " : " + d);
	}

}
